/* **********************************************************************************
 *
 * Copyright (c) TMF.AscendedThemeKit.Unthemed.NET Project. All rights reserved.
 *
 * This source code is subject to terms and conditions of the Shared Source License
 * for TMF.AscendedThemeKit.Unthemed. A copy of the license can be found in the License.html file
 * at the root of this distribution. If you can not locate the Shared Source License
 * for TMF.AscendedThemeKit.Unthemed, please send an email to ascend_adm@hotmail.com.
 * By using this source code in any fashion, you are agreeing to be bound by
 * the terms of the Shared Source License for TMF.AscendedThemeKit.Unthemed.NET.
 *
 * You must not remove this notice, or any other, from this software.
 *
 * **********************************************************************************/

using TMF.AscendedThemeKit.Unthemed.Resources;
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Collections;

namespace TMF.AscendedThemeKit.Unthemed.Windows.Forms
{
    /// <summary>
    ///  Renders a gradient navigation button pane based on properties.
    /// </summary>
    public class NavigationPaneRender : IDisposable
    {
        private Color _adjustedBorderColorAll;
        private Color _adjustedBorderColorBottom;
        private Color _adjustedBorderColorLeft;
        private Color _adjustedBorderColorRight;
        private Color _adjustedBorderColorTop;
        private Border _border = new Border(1);
        private BorderColor _borderColor = new BorderColor(SystemColors.ActiveCaption);
        private Rectangle _displayRectangle;
        private bool _enabled = true;
        private bool _antiAlias;
        private Color _backColor;
        private GradientCaptionRender _captionRender;
        private GradientCaptionRender _footerRender;
        private GradientNavigationButtonRender _footerSelectRender;
        private int _captionHeight;
        private int _footerHeight;
        private int _buttonHeight;
        private GradientSplitBarRender _splitBarRender;
        private int _splitBarTop;
        private int _splitBarHeight;
        private int _bottomAreaHeight;
        private int _configureFooterWidth;
        private NavigationPane _parentNavigationPane;
        private GradientNavigationButtonRender _gradientNavigationButtonRender;
        private int _highlightIndex;
        private int _activeIndex;
        private bool _configureFooterHighlight;
        private int _displayButtonCount;
        private int _buttonMinimizedWidth;
        private bool _disposed;
        private bool _showImageInCaption;
        private bool _useCompatibleTextRendering;
        private ArrayList _displayOrder = new ArrayList();
        private int _maxMinimizedCount;
        private Color _footerGradientHighColor;
        private Color _footerGradientLowColor;
        private Color _defaultButtonGradientHighColor;
        private Color _defaultButtonGradientLowColor;
        private Color _buttonBorderColor;
        private RenderMode _renderMode;
        private bool _rightToLeft;
        private ContentAlignment _defaultButtonTextAlign;
        private ContentAlignment _defaultButtonImageAlign;
        private Color _defaultButtonForeColor;
        private Color _defaultButtonActiveGradientHighColor;
        private Color _defaultButtonActiveGradientLowColor;
        private Color _defaultButtonHighlightGradientHighColor;
        private Color _defaultButtonHighlightGradientLowColor;

        /// <summary>
        /// Occurs when the AntiAlias property changes.
        /// </summary>
        [ResourceDescriptionAttribute("AntiAliasChangedDescription"), ResourceCategoryAttribute("PropertyChangedCategory")]
        public event EventHandler AntiAliasChanged;

        /// <summary>
        /// Occurs when the Border property changes.
        /// </summary>
        [ResourceDescriptionAttribute("BorderChangedDescription"), ResourceCategoryAttribute("PropertyChangedCategory")]
        public event EventHandler BorderChanged;

        /// <summary>
        /// Occurs when the BorderColor property changes.
        /// </summary>
        [ResourceDescriptionAttribute("BorderColorChangedDescription"), ResourceCategoryAttribute("PropertyChangedCategory")]
        public event EventHandler BorderColorChanged;

        /// <summary>
        /// Occurs when the BackColor property changes. 
        /// </summary>
        public event EventHandler BackColorChanged;

        /// <summary>
        /// Occurs when the Enabled property changes.
        /// </summary>
        internal event EventHandler EnabledChanged;

        /// <summary>
        /// Initializes a new instance of the NavigationPaneRender class.
        /// </summary>
        /// <param name="parentControl">The parent navigation pane control.</param>
        public NavigationPaneRender(NavigationPane parentControl)
        {
            if (parentControl == null)
            {
                throw new ArgumentNullException("parentControl");

            }
            
            this._parentNavigationPane = parentControl;

            this._renderMode = RenderMode.Gradient;
            this._defaultButtonTextAlign = ContentAlignment.MiddleLeft;
            this._defaultButtonImageAlign = ContentAlignment.MiddleLeft;
            this._defaultButtonForeColor = SystemColors.ControlText;
            this._defaultButtonGradientHighColor = SystemColors.ButtonHighlight;
            this._defaultButtonGradientLowColor = SystemColors.GradientActiveCaption;
            this._defaultButtonActiveGradientHighColor = Color.FromArgb(255, 225, 155);
            this._defaultButtonActiveGradientLowColor = Color.FromArgb(255, 165, 78);
            this._defaultButtonHighlightGradientHighColor = Color.White;
            this._defaultButtonHighlightGradientLowColor = Color.FromArgb(255, 165, 78);

            this._captionRender = new GradientCaptionRender();
            this._captionRender.Border = new Border(0);

            this._captionRender.ForeColor = SystemColors.ActiveCaptionText;
            this._captionRender.Border = new Border(0, 0, 0, 1);
            this._captionRender.BorderColor = new BorderColor(SystemColors.ActiveCaption);
            this._captionRender.RenderMode = this._renderMode;

            this._footerGradientHighColor = SystemColors.ButtonHighlight;
            this._footerGradientLowColor = SystemColors.GradientActiveCaption;

            this._footerRender = new GradientCaptionRender();
            this._footerRender.GradientMode = LinearGradientMode.Vertical;
            this._footerRender.GradientHighColor = this._footerGradientHighColor;
            this._footerRender.GradientLowColor = this._footerGradientLowColor;
            this._footerRender.Border = new Border(0, 1, 0, 0);
            this._footerRender.BorderColor = new BorderColor(SystemColors.ActiveCaption);
            this._footerRender.RenderMode = this._renderMode;

            this._footerSelectRender = new GradientNavigationButtonRender();
            this._footerSelectRender.GradientMode = LinearGradientMode.Vertical;
            this._footerSelectRender.GradientHighColor = this._footerGradientHighColor;
            this._footerSelectRender.GradientLowColor = this._footerGradientLowColor;
            this._footerSelectRender.HighlightGradientHighColor = Color.White;
            this._footerSelectRender.HighlightGradientLowColor = Color.FromArgb(255, 165, 78);
            this._footerSelectRender.Image = TMF.AscendedThemeKit.Properties.Resources.NavigationPaneChevron.ToBitmap();
            this._footerSelectRender.ImageAlign = ContentAlignment.MiddleCenter;
            this._footerSelectRender.Border = new Border(0, 1, 0, 0);
            this._footerSelectRender.BorderColor = new BorderColor(SystemColors.ActiveCaption);
            this._footerSelectRender.RenderMode = this._renderMode;

            this._splitBarRender = new GradientSplitBarRender();
            this._splitBarRender.BorderColor = new BorderColor(SystemColors.MenuHighlight);
            this._splitBarRender.Border = new Border(0, 1, 0, 0);
            this._splitBarRender.BorderColor = new BorderColor(SystemColors.ActiveCaption);
            this._splitBarRender.RenderMode = this._renderMode;

            this._gradientNavigationButtonRender = new GradientNavigationButtonRender();
            this._gradientNavigationButtonRender.GradientHighColor = SystemColors.ButtonHighlight;
            this._gradientNavigationButtonRender.GradientLowColor = SystemColors.GradientActiveCaption;
            this._gradientNavigationButtonRender.ForeColor = SystemColors.ControlText;
            this._gradientNavigationButtonRender.TextAlign = ContentAlignment.MiddleLeft;
            this._gradientNavigationButtonRender.RenderMode = this._renderMode;

            this._buttonBorderColor = SystemColors.MenuHighlight;

            this._gradientNavigationButtonRender.Border = new Border(0, 1, 0, 0);
            this._gradientNavigationButtonRender.BorderColor = new BorderColor(this._buttonBorderColor);
            this._gradientNavigationButtonRender.Padding = new Padding(4, 0, 4, 0);

            this._captionHeight = 26;
            this._footerHeight = 30;
            this._splitBarHeight = 7;
            this._buttonHeight = 32;
            this._highlightIndex = -1;
            this._configureFooterWidth = 20;
            this._buttonMinimizedWidth = 24;

        }

        /// <summary>
        /// Gets or sets the border for the control.
        /// </summary>
        /// <value>
        /// 	<para>
        /// Border. An object of type Border representing the control's border width characteristics.
        /// </para>
        /// 	<para>
        /// This property is read/write.
        /// </para>
        /// </value>
        /// <remarks>
        /// For containers such as GradientPanel and GradientCaption, the Border property gets or sets their respective border widths inside the DisplayRectangle.
        /// </remarks>
        public Border Border
        {
            get
            {
                return this._border;

            }

            set
            {
                if (value == this.Border)
                {
                    return;

                }

                this._border = value;

                this.OnBorderChanged(new EventArgs());

            }

        }

        /// <summary>
        /// Gets or sets the border color(s) for the control.
        /// </summary>
        /// <value>
        /// 	<para>
        /// BorderColor. An object of type Border representing the control's border color characteristics.
        /// </para>
        /// 	<para>
        /// This property is read/write.
        /// </para>
        /// </value>
        /// <remarks>
        /// For containers such as GradientPanel and GradientCaption, the BorderColor property gets or sets their respective border colors inside the DisplayRectangle.
        /// </remarks>
        public BorderColor BorderColor
        {
            get
            {
                return this._borderColor;

            }

            set
            {
                if (value == this._borderColor)
                {
                    return;

                }

                this._borderColor = value;

                this.CreateColors();

                this.OnBorderColorChanged(new EventArgs());

            }

        }

        /// <summary>
        /// Gets or sets a value indicating whether the control can respond to user interaction.
        /// </summary>
        /// <value>
        /// 	<para>
        /// System.Boolean . true if the control can respond to user interaction; otherwise, false. The default is true. 
        /// </para>
        /// 	<para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        public bool Enabled
        {
            get
            {
                return this._enabled;

            }

            set
            {
                if (value == this._enabled)
                {
                    return;

                }

                this._enabled = value;

                this.CreateColors();

            }

        }

        /// <summary>
        /// The display rectangle to render to.
        /// </summary>
        public Rectangle DisplayRectangle
        {
            get
            {
                return this._displayRectangle;

            }

            set
            {
                this._displayRectangle = value;

            }

        }

        /// <summary>
        /// Specifies the rendering hint for the control.
        /// </summary>
        /// <value>
        /// 	<para>
        /// System.Boolean . Specifies if the rendering should use antialiasing.
        /// </para>
        /// 	<para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        public bool AntiAlias
        {
            get
            {
                return this._antiAlias;

            }

            set
            {
                if (value == this._antiAlias)
                {
                    return;

                }

                this._antiAlias = value;

                this.CreateColors();

                this.OnAntiAliasChanged(new EventArgs());

            }

        }

        /// <summary>
        /// Specifies the back color for the control.
        /// </summary>
        /// <value>
        /// 	<para>
        /// System.Drawing.Color . Specifies the color to use on the background.
        /// </para>
        /// 	<para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        public Color BackColor
        {
            get
            {
                return this._backColor;

            }

            set
            {
                if (value == this._backColor)
                {
                    return;

                }

                this._backColor = value;

                this.OnBackColorChanged(new EventArgs());

            }

        }

        internal Rectangle PanelRectangle
        {
            get
            {
                return new Rectangle((this.DisplayRectangle.Left + this._border.Left), this._captionRender.DisplayRectangle.Bottom, (this.DisplayRectangle.Width - this._border.Right), (this._splitBarRender.DisplayRectangle.Top - this._captionRender.DisplayRectangle.Bottom));

            }

        }

        /// <summary>
        /// Gets the splitbar display rectangle.
        /// </summary>
        public Rectangle SplitBarRectangle
        {
            get
            {
                return this._splitBarRender.DisplayRectangle;

            }

        }

        /// <summary>
        /// Gets or sets the split bar gradient high color.
        /// </summary>
        public Color SplitBarGradientHighColor
        {
            get
            {
                return this._splitBarRender.GradientHighColor;

            }

            set
            {
                if (value == this._splitBarRender.GradientHighColor)
                {
                    return;

                }

                this._splitBarRender.GradientHighColor = value;

            }

        }

        /// <summary>
        /// Gets or sets the split bar gradient low color.
        /// </summary>
        public Color SplitBarGradientLowColor
        {
            get
            {
                return this._splitBarRender.GradientLowColor;

            }

            set
            {
                if (value == this._splitBarRender.GradientLowColor)
                {
                    return;

                }

                this._splitBarRender.GradientLowColor = value;

            }

        }

        /// <summary>
        /// Gets or sets the split bar height.
        /// </summary>
        public int SplitBarHeight
        {
            get
            {
                return this._splitBarHeight;

            }

            set
            {
                if (value == this._splitBarHeight)
                {
                    return;

                }

                this._splitBarHeight = value;

            }

        }

        /// <summary>
        /// Gets or sets the split bar border color
        /// </summary>
        public Color SplitBarBorderColor
        {
            get
            {
                return this._splitBarRender.BorderColor.Top;

            }

            set
            {
                if (value == this._splitBarRender.BorderColor.Top)
                {
                    return;

                }

                this._splitBarRender.BorderColor = new BorderColor(value);

            }

        }

        /// <summary>
        /// Gets or sets the current highlighted button index.
        /// </summary>
        public int HighlightIndex
        {
            get
            {
                return this._highlightIndex;

            }

            set
            {
                this._highlightIndex = value;

            }

        }

        /// <summary>
        /// Specifies the painting style applied to the background in a control.
        /// </summary>
        public RenderMode RenderMode
        {
            get
            {
                return this._renderMode;

            }

            set
            {
                if (value == this._renderMode)
                {
                    return;

                }

                this._renderMode = value;

                this.ResetRenderMode();

            }

        }

        /// <summary>
        /// Gets or sets the current active buton index.
        /// </summary>
        public int ActiveIndex
        {
            get
            {
                return this._activeIndex;

            }

            set
            {
                this._activeIndex = value;

            }

        }

        /// <summary>
        /// Gets the footer configure display rectangle.
        /// </summary>
        public Rectangle FooterConfigureRectangle
        {
            get
            {
                return this._footerSelectRender.DisplayRectangle;

            }

        }

        /// <summary>
        /// Gets or sets the footer gradient high color.
        /// </summary>
        public Color FooterGradientHighColor
        {
            get 
            { 
                return this._footerGradientHighColor;
            
            }

            set 
            { 
                this._footerGradientHighColor = value;
            
            }

        }

        /// <summary>
        /// Gets or sets the footer gradient low color.
        /// </summary>
        public Color FooterGradientLowColor
        {
            get
            {
                return this._footerGradientLowColor;

            }

            set
            {
                this._footerGradientLowColor = value;

            }

        }

        /// <summary>
        /// Gets or sets the footer height.
        /// </summary>
        public int FooterHeight
        {
            get
            {
                return this._footerHeight;

            }

            set
            {
                this._footerHeight = value;

            }

        }

        /// <summary>
        /// Gets or sets the footer gradient high (lighter) color for the control when it is moused over.
        /// </summary>
        public Color FooterHighlightGradientHighColor
        {
            get
            {
                return this._footerSelectRender.HighlightGradientHighColor;

            }

            set
            {
                this._footerSelectRender.HighlightGradientHighColor = value;
                this._footerSelectRender.ActiveGradientHighColor = value;

            }

        }

        /// <summary>
        /// Gets or sets the footer gradient low (darker) color for the control when it is moused over.
        /// </summary>
        public Color FooterHighlightGradientLowColor
        {
            get
            {
                return this._footerSelectRender.HighlightGradientLowColor;

            }

            set
            {
                this._footerSelectRender.HighlightGradientLowColor = value;
                this._footerSelectRender.ActiveGradientLowColor = value;

            }

        }

        /// <summary>
        /// 
        /// </summary>
        public bool ConfigureFooterHighlight
        {
            get
            {
                return this._configureFooterHighlight;

            }

            set
            {
                this._configureFooterHighlight = value;

            }

        }

        /// <summary>
        /// Gets the footer display rectangle.
        /// </summary>
        public Rectangle FooterRectangle
        {
            get
            {
                return this._footerRender.DisplayRectangle;

            }

        }

        /// <summary>
        /// Gets the caption display rectangle.
        /// </summary>
        public Rectangle CaptionRectangle
        {
            get
            {
                return this._captionRender.DisplayRectangle;

            }

        }

        /// <summary>
        /// Gets or sets the button active gradient high color.
        /// </summary>
        public Color ButtonActiveGradientHighColor
        {
            get
            {
                return this._defaultButtonActiveGradientHighColor;

            }

            set
            {
                if (value == this._defaultButtonActiveGradientHighColor)
                {
                    return;

                }

                this._defaultButtonActiveGradientHighColor = value;
                this._gradientNavigationButtonRender.ActiveGradientHighColor = value;

            }

        }

        /// <summary>
        /// Gets or sets the button active gradient low color.
        /// </summary>
        public Color ButtonActiveGradientLowColor
        {
            get
            {
                return this._defaultButtonActiveGradientLowColor;

            }

            set
            {
                if (value == this._defaultButtonActiveGradientLowColor)
                {
                    return;

                }

                this._defaultButtonActiveGradientLowColor = value;
                this._gradientNavigationButtonRender.ActiveGradientLowColor = value;

            }

        }

        /// <summary>
        /// Gets or sets the button border color.
        /// </summary>
        public Color ButtonBorderColor
        {
            get
            {
                return this._buttonBorderColor;

            }

            set
            {
                if (value == this._buttonBorderColor)
                {
                    return;

                }

                this._buttonBorderColor = value;

            }

        }

        /// <summary>
        /// Gets or sets the button forecolor.
        /// </summary>
        public Color ButtonForeColor
        {
            get
            {
                return this._defaultButtonForeColor;

            }

            set
            {
                this._defaultButtonForeColor = value;
                this._gradientNavigationButtonRender.ForeColor = value;

            }

        }

        /// <summary>
        /// Gets or sets the button font.
        /// </summary>
        public Font ButtonFont
        {
            get
            {
                return this._gradientNavigationButtonRender.Font;

            }

            set
            {
                this._gradientNavigationButtonRender.Font = value;

            }

        }

        /// <summary>
        /// Gets or sets the button gradient high color.
        /// </summary>
        public Color ButtonGradientHighColor
        {
            get
            {
                return this._defaultButtonGradientHighColor;

            }

            set
            {
                if (value == this._defaultButtonGradientHighColor)
                {
                    return;

                }

                this._defaultButtonGradientHighColor = value;
                this._gradientNavigationButtonRender.GradientHighColor = value;

            }

        }

        /// <summary>
        /// Gets or sets the button gradient low color.
        /// </summary>
        public Color ButtonGradientLowColor
        {
            get
            {
                return this._defaultButtonGradientLowColor;

            }

            set
            {
                if (value == this._defaultButtonGradientLowColor)
                {
                    return;

                }

                this._defaultButtonGradientLowColor = value;
                this._gradientNavigationButtonRender.GradientLowColor = value;

            }

        }

        /// <summary>
        /// Gets or sets the buttun height
        /// </summary>
        public int ButtonHeight
        {
            get
            {
                return this._buttonHeight;

            }

            set
            {
                if (value == this._buttonHeight)
                {
                    return;

                }

                this._buttonHeight = value;

            }

        }

        /// <summary>
        /// Gets or sets the gradient high (lighter) color for the button when it is moused over.
        /// </summary>
        public Color ButtonHighlightGradientHighColor
        {
            get
            {
                return this._defaultButtonHighlightGradientHighColor;

            }

            set
            {
                if (value == this._defaultButtonHighlightGradientHighColor)
                {
                    return;

                }

                this._defaultButtonHighlightGradientHighColor = value;
                this._gradientNavigationButtonRender.HighlightGradientHighColor = value;

            }

        }

        /// <summary>
        /// Gets or sets the gradient high (lighter) color for the button when it is moused over.
        /// </summary>
        public Color ButtonHighlightGradientLowColor
        {
            get
            {
                return this._defaultButtonHighlightGradientLowColor;

            }

            set
            {
                if (value == this._defaultButtonHighlightGradientLowColor)
                {
                    return;

                }

                this._defaultButtonHighlightGradientLowColor = value;
                this._gradientNavigationButtonRender.HighlightGradientLowColor = value;

            }

        }

        /// <summary>
        /// Gets or sets the default button image alignment.
        /// </summary>
        public ContentAlignment ButtonImageAlign
        {
            get
            {
                return this._defaultButtonImageAlign;

            }

            set
            {
                this._defaultButtonImageAlign = value;
                this._gradientNavigationButtonRender.ImageAlign = value;

            }

        }

        /// <summary>
        /// Gets or sets the default button text aligment.
        /// </summary>
        public ContentAlignment ButtonTextAlign
        {
            get
            {
                return this._defaultButtonTextAlign;

            }

            set
            {
                this._defaultButtonTextAlign = value;
                this._gradientNavigationButtonRender.TextAlign = value;

            }

        }

        /// <summary>
        /// Gets or sets number of buttons to display (render).
        /// </summary>
        public int DisplayButtonCount
        {
            get
            {
                return this._displayButtonCount;

            }

            set
            {
                this._displayButtonCount = value;

            }

        }

        /// <summary>
        /// Gets or sets the caption border color.
        /// </summary>
        public Color CaptionBorderColor
        {
            get
            {
                return this._captionRender.BorderColor.Bottom;

            }

            set
            {
                if (value == this._captionRender.BorderColor.Bottom)
                {
                    return;

                }

                this._captionRender.BorderColor = new BorderColor(value);

            }

        }

        /// <summary>
        /// Gets or sets the caption height.
        /// </summary>
        public int CaptionHeight
        {
            get
            {
                return this._captionHeight;

            }

            set
            {
                this._captionHeight = value;

            }

        }

        /// <summary>
        /// gets or sets the caption image alignment.
        /// </summary>
        public ContentAlignment CaptionImageAlign
        {
            get
            {
                return this._captionRender.ImageAlign;

            }

            set
            {
                this._captionRender.ImageAlign = value;

            }

        }

        /// <summary>
        /// gets or sets the caption text alignment.
        /// </summary>
        public ContentAlignment CaptionTextAlign
        {
            get
            {
                return this._captionRender.TextAlign;

            }

            set
            {
                this._captionRender.TextAlign = value;

            }

        }

        /// <summary>
        /// Gets or sets the caption font.
        /// </summary>
        public Font CaptionFont
        {
            get
            {
                return this._captionRender.Font;

            }

            set
            {
                this._captionRender.Font = value;

            }

        }

        /// <summary>
        /// Gets or sets the caption forecolor.
        /// </summary>
        public Color CaptionForeColor
        {
            get
            {
                return this._captionRender.ForeColor;

            }

            set
            {
                this._captionRender.ForeColor = value;

            }

        }

        /// <summary>
        /// Gets or sets the caption gradient high color.
        /// </summary>
        public Color CaptionGradientHighColor
        {
            get
            {
                return this._captionRender.GradientHighColor;
            }

            set
            {
                this._captionRender.GradientHighColor = value;

            }

        }

        /// <summary>
        /// Gets or sets the caption gradient low color.
        /// </summary>
        public Color CaptionGradientLowColor
        {
            get
            {
                return this._captionRender.GradientLowColor;

            }

            set
            {
                this._captionRender.GradientLowColor = value;

            }

        }

        /// <summary>
        /// Specifies the direction of a linear gradient for the caption.
        /// </summary>
        /// <value>
        /// 	<para>
        /// System.Drawing.Drawing2D.LinearGradientMode . Specifies the direction of a linear gradient.
        /// </para>
        /// 	<para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        public LinearGradientMode CaptionGradientMode
        {
            get
            {
                return this._captionRender.GradientMode;

            }

            set
            {
                if (value == this._captionRender.GradientMode)
                {
                    return;

                }

                this._captionRender.GradientMode = value;

            }

        }

        /// <summary>
        /// Gets or sets if the control should render text right to left.
        /// </summary>
        public bool RightToLeft
        {
            get 
            { 
                return this._rightToLeft;
            
            }

            set 
            {
                if (this._rightToLeft == value)
                {
                    return;

                }

                this._rightToLeft = value;

                this._captionRender.RightToLeft = value;
                this._gradientNavigationButtonRender.RightToLeft = value;
                
            }

        }

        /// <summary>
        /// Gets or sets if the currently active button image is shown in the caption.
        /// </summary>
        public bool ShowImageInCaption
        {
            get
            {
                return this._showImageInCaption;

            }

            set
            {
                if (value == this._showImageInCaption)
                {
                    return;

                }

                this._showImageInCaption = value;

            }

        }

        /// <summary>
        /// Gets or sets the display order list.
        /// </summary>
        public ArrayList DisplayOrder
        {
            get
            {
                return this._displayOrder;

            }

        }

        /// <summary>
        /// Gets or sets a value that determines whether to use the compatible text rendering engine (GDI+) or not (GDI). 
        /// </summary>
        /// <value>
        /// true if the compatible text rendering engine (GDI+) is used; otherwise, false. 
        /// </value>
        public bool UseCompatibleTextRendering
        {
            get
            {
                return this._useCompatibleTextRendering;

            }

            set
            {
                this._useCompatibleTextRendering = value;

                this._gradientNavigationButtonRender.UseCompatibleTextRendering = value;
                this._captionRender.UseCompatibleTextRendering = value;

            }

        }

        #region IDisposable Members

        /// <summary>
        /// Releases all resources used.
        /// </summary>
        public void Dispose()
        {
            this.Dispose(true);

            GC.SuppressFinalize(this);

            return;

        }

        /// <summary>
        /// Releases all resources used.
        /// </summary>
        /// <param name="disposing">true or false</param>
        protected virtual void Dispose(bool disposing)
        {
            if (!this._disposed)
            {
                if (disposing)
                {
                    if (this._captionRender != null) this._captionRender.Dispose();
                    if (this._footerRender != null) this._footerRender.Dispose();
                    if (this._footerSelectRender != null) this._footerSelectRender.Dispose();
                    if (this._gradientNavigationButtonRender != null) this._gradientNavigationButtonRender.Dispose();
                    if (this._splitBarRender != null) this._splitBarRender.Dispose();

                }

            }

            this._disposed = true;

        }

        /// <summary>
        /// Creates the colors used to draw the control.
        /// </summary>
        /// <remarks>
        /// Takes the alpha and enabled into account.
        /// </remarks>
        protected void CreateColors()
        {
            if (this.Enabled)
            {
                if (this._borderColor.ShouldSerializeAll())
                {
                    this._adjustedBorderColorAll = this._borderColor.All;

                    this._adjustedBorderColorLeft = this._adjustedBorderColorAll;
                    this._adjustedBorderColorTop = this._adjustedBorderColorAll;
                    this._adjustedBorderColorRight = this._adjustedBorderColorAll;
                    this._adjustedBorderColorBottom = this._adjustedBorderColorAll;

                }
                else
                {
                    this._adjustedBorderColorLeft = this._borderColor.Left;
                    this._adjustedBorderColorTop = this._borderColor.Top;
                    this._adjustedBorderColorRight = this._borderColor.Right;
                    this._adjustedBorderColorBottom = this._borderColor.Bottom;

                }

            }
            else
            {
                if (this._borderColor.ShouldSerializeAll())
                {
                    ExtendedColor grayscaleBorderAll = new ExtendedColor(this._borderColor.All, 0.0d);
                    this._adjustedBorderColorAll = grayscaleBorderAll;

                }
                else
                {
                    ExtendedColor grayscaleBorderLeft = new ExtendedColor(this._borderColor.Left, 0.0d);
                    this._adjustedBorderColorLeft = grayscaleBorderLeft;

                    ExtendedColor grayscaleBorderTop = new ExtendedColor(this._borderColor.Top, 0.0d);
                    this._adjustedBorderColorTop = grayscaleBorderTop;

                    ExtendedColor grayscaleBorderRight = new ExtendedColor(this._borderColor.Right, 0.0d);
                    this._adjustedBorderColorRight = grayscaleBorderRight;

                    ExtendedColor grayscaleBorderBottom = new ExtendedColor(this._borderColor.Bottom, 0.0d);
                    this._adjustedBorderColorBottom = grayscaleBorderBottom;

                }

            }

        }

        /// <summary>
        /// Fires the event indicating that the control antialias has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnAntiAliasChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected void OnAntiAliasChanged(EventArgs e)
        {
            this._captionRender.AntiAlias = this._antiAlias;
            this._footerRender.AntiAlias = this._antiAlias;
            this._footerSelectRender.AntiAlias = this._antiAlias;
            this._gradientNavigationButtonRender.AntiAlias = this._antiAlias;
            this._splitBarRender.AntiAlias = this._antiAlias;

            if (this.AntiAliasChanged != null)
            {
                this.AntiAliasChanged(this, e);

            }

        }

        /// <summary>
        /// Fires the event indicating that the control Border has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnBorderChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected void OnBorderChanged(EventArgs e)
        {
            if (this.BorderChanged != null)
            {
                this.BorderChanged(this, e);

            }

        }

        /// <summary>
        /// Fires the event indicating that the control BorderColor has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnBorderColorChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected void OnBorderColorChanged(EventArgs e)
        {
            if (this.BorderColorChanged != null)
            {
                this.BorderColorChanged(this, e);

            }

        }

        /// <param name="e">An System.EventArgs that contains the event data.</param>
        protected virtual void OnEnabledChanged(System.EventArgs e)
        {
            this.CreateColors();

            if (this.EnabledChanged != null)
            {
                this.EnabledChanged(this, e);

            }

        }

        /// <summary>
        /// Renders the gradient background.
        /// </summary>
        /// <param name="e">Provides data for the Paint event.</param>
        public virtual void Render(PaintEventArgs e)
        {
            if (this.DisplayRectangle != null)
            {
                if (this.DisplayRectangle.Width > 0 && this.DisplayRectangle.Height > 0)
                {
                    int currentButtonTop;
                    int currentMinimizedButtonLeft;
                    int configureFooterLeft;
                    int footerTop;
                    int index = -1;
                    int totalMinimized = ((this._displayOrder.Count - (this._displayOrder.Count - this._parentNavigationPane.NavigationPages.VisibleCount)) - this._displayButtonCount);

                    this.SetRenderingHints(e);
                    this.CreateColors();
                    this.DrawSquareBackgound(e);

                    this.DetermineMaxMinimizedButtonCount();

                    this._captionRender.DisplayRectangle = new Rectangle((this.DisplayRectangle.Left + this._border.Left), (this.DisplayRectangle.Top + this._border.Top), (this.DisplayRectangle.Width - this._border.Right), this._captionHeight);

                    currentButtonTop = (this.DisplayRectangle.Bottom - this._footerHeight);
                    this._bottomAreaHeight = 0;

                    footerTop = (this.DisplayRectangle.Bottom - (this._border.Bottom + (this._footerHeight - 1)));

                    configureFooterLeft = (this.DisplayRectangle.Right - this._configureFooterWidth);
                    currentMinimizedButtonLeft = configureFooterLeft;

                    Rectangle buttonRectangle;

                    int displayedCount = this._parentNavigationPane.NavigationPages.DisplayCount;

                    for (int i = (this._displayOrder.Count - 1); i > -1; i--)
                    {
                        index = this._parentNavigationPane.NavigationPages.IndexOf(this._displayOrder[i].ToString());

                        if (index > -1)
                        {
                            if (this._parentNavigationPane.NavigationPages[index].Visible && this._parentNavigationPane.NavigationPages[index].ButtonVisible)
                            {
                                if (displayedCount <= this._displayButtonCount)
                                {
                                    currentButtonTop -= this._buttonHeight;
                                    this._bottomAreaHeight += this._buttonHeight;

                                    this._gradientNavigationButtonRender.ImageAlign = this._parentNavigationPane.NavigationPages[index].ImageAlign;
                                    this._gradientNavigationButtonRender.TextAlign = this._parentNavigationPane.NavigationPages[index].TextAlign;
                                    this._gradientNavigationButtonRender.Text = this._parentNavigationPane.NavigationPages[index].Text;
                                    this._gradientNavigationButtonRender.ForeColor = this._parentNavigationPane.NavigationPages[index].ButtonForeColor;
                                    this._gradientNavigationButtonRender.GradientHighColor = this._parentNavigationPane.NavigationPages[index].GradientHighColor;
                                    this._gradientNavigationButtonRender.GradientLowColor = this._parentNavigationPane.NavigationPages[index].GradientLowColor;
                                    this._gradientNavigationButtonRender.ActiveGradientHighColor = this._parentNavigationPane.NavigationPages[index].ActiveGradientHighColor;
                                    this._gradientNavigationButtonRender.ActiveGradientLowColor = this._parentNavigationPane.NavigationPages[index].ActiveGradientLowColor;
                                    this._gradientNavigationButtonRender.HighlightGradientHighColor = this._parentNavigationPane.NavigationPages[index].HighlightGradientHighColor;
                                    this._gradientNavigationButtonRender.HighlightGradientLowColor = this._parentNavigationPane.NavigationPages[index].HighlightGradientLowColor;
                                    this._gradientNavigationButtonRender.BorderColor = new BorderColor(this._buttonBorderColor);
                                    this._gradientNavigationButtonRender.BorderColor = new BorderColor(this._buttonBorderColor);
                                    this._gradientNavigationButtonRender.Image = this._parentNavigationPane.NavigationPages[index].Image;
                                    this._gradientNavigationButtonRender.Font = this._parentNavigationPane.NavigationPages[index].ButtonFont;

                                    buttonRectangle = new Rectangle((this.DisplayRectangle.Left + this._border.Left), currentButtonTop, (this.DisplayRectangle.Width - this._border.Right), this._buttonHeight);
                                    this._parentNavigationPane.NavigationPages[index].ButtonMinimized = false;

                                }
                                else
                                {
                                    if (totalMinimized <= this._maxMinimizedCount)
                                    {
                                        currentMinimizedButtonLeft -= this._buttonMinimizedWidth;

                                        bool resetAntialias = this._gradientNavigationButtonRender.AntiAlias;
                                        if (this._gradientNavigationButtonRender.AntiAlias) this._gradientNavigationButtonRender.AntiAlias = false;

                                        this._gradientNavigationButtonRender.ImageAlign = ContentAlignment.MiddleCenter;
                                        this._gradientNavigationButtonRender.GradientHighColor = this._footerGradientHighColor;
                                        this._gradientNavigationButtonRender.GradientLowColor = this._footerGradientLowColor;

                                        if (this._parentNavigationPane.NavigationPages[index].ImageFooter != null)
                                        {
                                            this._gradientNavigationButtonRender.Image = this._parentNavigationPane.NavigationPages[index].ImageFooter;

                                        }
                                        else
                                        {
                                            this._gradientNavigationButtonRender.Image = this._parentNavigationPane.NavigationPages[index].Image;

                                        }

                                        buttonRectangle = new Rectangle(currentMinimizedButtonLeft, footerTop, this._buttonMinimizedWidth, this._footerHeight);
                                        this._parentNavigationPane.NavigationPages[index].ButtonMinimizedVisible = true;

                                        if (resetAntialias) this._gradientNavigationButtonRender.AntiAlias = true;

                                    }
                                    else
                                    {
                                        buttonRectangle = Rectangle.Empty;
                                        this._parentNavigationPane.NavigationPages[index].ButtonMinimizedVisible = false;

                                    }

                                    totalMinimized--;

                                    this._gradientNavigationButtonRender.Text = string.Empty;
                                    this._parentNavigationPane.NavigationPages[index].ButtonMinimized = true;

                                }

                                displayedCount--;

                                this._parentNavigationPane.NavigationPages[index].ButtonRectangle = buttonRectangle;

                                if (i == this._activeIndex)
                                {
                                    this._gradientNavigationButtonRender.Active = true;
                                    this._captionRender.Text = this._parentNavigationPane.NavigationPages[index].Text;

                                    if (this._showImageInCaption)
                                    {
                                        this._captionRender.Image = this._gradientNavigationButtonRender.Image;

                                    }
                                    else
                                    {
                                        this._captionRender.Image = null;

                                    }

                                }
                                else
                                {
                                    this._gradientNavigationButtonRender.Active = false;

                                }

                                this._gradientNavigationButtonRender.Highlight = i == this._highlightIndex ? true : false;
                                this._gradientNavigationButtonRender.Enabled = this._parentNavigationPane.NavigationPages[index].Enabled;
                                this._gradientNavigationButtonRender.DisplayRectangle = buttonRectangle;

                                this._gradientNavigationButtonRender.Render(e);

                            }

                        }

                    }

                    this._captionRender.Render(e);

                    this._splitBarTop = (this.DisplayRectangle.Bottom - this._footerHeight - this._bottomAreaHeight - this._splitBarHeight);

                    this._splitBarRender.DisplayRectangle = new Rectangle((this.DisplayRectangle.Left + this._border.Left), this._splitBarTop, (this.DisplayRectangle.Width - this._border.Right), this._splitBarHeight);
                    this._splitBarRender.Render(e);

                    this._footerSelectRender.DisplayRectangle = new Rectangle(configureFooterLeft, footerTop, this._configureFooterWidth, this._footerHeight);
                    this._footerSelectRender.GradientHighColor = this._footerGradientHighColor;
                    this._footerSelectRender.GradientLowColor = this._footerGradientLowColor;
                    this._footerSelectRender.Active = this._configureFooterHighlight;
                    this._footerSelectRender.BorderColor = new BorderColor(this._buttonBorderColor);
                    this._footerSelectRender.Render(e);

                    this._footerRender.DisplayRectangle = new Rectangle((this.DisplayRectangle.Left + this._border.Left), footerTop, (currentMinimizedButtonLeft - this.DisplayRectangle.Left), this._footerHeight);
                    this._footerRender.GradientHighColor = this._footerGradientHighColor;
                    this._footerRender.GradientLowColor = this._footerGradientLowColor;
                    this._footerRender.BorderColor = new BorderColor(this._buttonBorderColor);
                    this._footerRender.Render(e);

                    //this._panelRectangle = this.PanelRectangle;

                }

            }

        }

        /// <summary>
        /// Sets the rendering hints based on the AntiAlias property.
        /// </summary>
        /// <param name="e">A System.Windows.Forms.PaintEventArgs that contains the event data.</param>
        /// <remarks>
        /// This methid must be called before any drawing methods are called.
        /// </remarks>
        private void SetRenderingHints(System.Windows.Forms.PaintEventArgs e)
        {
            if (this._antiAlias)
            {
                e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
                e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

            }
            else
            {
                e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SystemDefault;
                e.Graphics.SmoothingMode = SmoothingMode.Default;

            }

        }

        #endregion

        /// <summary>
        /// Fires the event indicating that the control backColor has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnBackColorChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        public void OnBackColorChanged(EventArgs e)
        {
            if (this.BackColorChanged != null)
            {
                this.BackColorChanged(this, e);

            }

        }

        /// <summary>
        /// Draws a square background.
        /// </summary>
        /// <param name="e">Provides data for the Paint event.</param>
        private void DrawSquareBackgound(PaintEventArgs e)
        {
            SolidBrush backBrush = new SolidBrush(this.BackColor);
            try
            {
                e.Graphics.FillRectangle(backBrush, this.DisplayRectangle);

                if (this._border.Top > 0)
                {
                    Pen topBorderPen = new Pen(this._adjustedBorderColorTop, this._border.Top);
                    try
                    {
                        float offset = (float)(this._border.Top / 2.0);
                        e.Graphics.DrawLine(topBorderPen, new PointF(this.DisplayRectangle.Left, (this.DisplayRectangle.Top + offset)), new PointF(this.DisplayRectangle.Right, (this.DisplayRectangle.Top + offset)));

                    }
                    catch
                    {
                        throw;

                    }
                    finally
                    {
                        topBorderPen.Dispose();

                    }

                }

                if (this._border.Bottom > 0)
                {
                    Pen botttomBorderPen = new Pen(this._adjustedBorderColorBottom, this._border.Bottom);
                    try
                    {
                        float offset = (float)Math.Floor((this._border.Bottom / 2.0));
                        e.Graphics.DrawLine(botttomBorderPen, new PointF(this.DisplayRectangle.Left, (this.DisplayRectangle.Bottom - offset)), new PointF(this.DisplayRectangle.Right, (this.DisplayRectangle.Bottom - offset)));

                    }
                    catch
                    {
                        throw;

                    }
                    finally
                    {
                        botttomBorderPen.Dispose();

                    }

                }

                if (this._border.Right > 0)
                {
                    Pen rightBorderPen = new Pen(this._adjustedBorderColorRight, this._border.Right);
                    try
                    {
                        float offset = (float)Math.Floor((this._border.Right / 2.0));
                        e.Graphics.DrawLine(rightBorderPen, new PointF((this.DisplayRectangle.Right - offset), this.DisplayRectangle.Top), new PointF((this.DisplayRectangle.Right - offset), this.DisplayRectangle.Bottom));

                    }
                    catch
                    {
                        throw;

                    }
                    finally
                    {
                        rightBorderPen.Dispose();

                    }

                }

                if (this._border.Left > 0)
                {
                    Pen leftBorderPen = new Pen(this._adjustedBorderColorLeft, this._border.Left);
                    try
                    {
                        float offset = (float)(this._border.Left / 2.0);
                        e.Graphics.DrawLine(leftBorderPen, new PointF((this.DisplayRectangle.Left + offset), this.DisplayRectangle.Top), new PointF((this.DisplayRectangle.Left + offset), this.DisplayRectangle.Bottom));

                    }
                    catch
                    {
                        throw;

                    }
                    finally
                    {
                        leftBorderPen.Dispose();

                    }

                }

            }
            catch
            {
                throw;

            }
            finally
            {
                backBrush.Dispose();

            }

        }

        /// <summary>
        /// Resets the colors associated with the control.
        /// </summary>
        public virtual void ResetColors()
        {
            this.CreateColors();

            this._captionRender.ResetColors();
            this._footerRender.ResetColors();
            this._footerSelectRender.ResetColors();
            this._gradientNavigationButtonRender.ResetColors();
            this._splitBarRender.ResetColors();

        }

        private void ResetRenderMode()
        {
            this._captionRender.RenderMode = this._renderMode;
            this._footerRender.RenderMode = this._renderMode;
            this._footerSelectRender.RenderMode = this._renderMode;
            this._splitBarRender.RenderMode = this._renderMode;
            this._gradientNavigationButtonRender.RenderMode = this._renderMode;

        }

        private void DetermineMaxMinimizedButtonCount()
        {
            this._maxMinimizedCount = (this.DisplayRectangle.Right - this._configureFooterWidth) / this._buttonMinimizedWidth;

        }

    }

}
